package nccloud.bs.gl.voucher;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import com.meterware.httpunit.dom.DocumentImpl;
import nc.bs.gl.voucher_list.event.util.SortDetailIndexUtil;
import nc.itf.uap.busibean.SysinitAccessor;
import nc.plugin.YFKHandlerUtil;
import nc.pubimpl.org.cache.AccountingBookQuery;
import org.w3c.dom.Document;
import org.w3c.dom.Element;


import nc.bd.accperiod.AccperiodAccessor;
import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.framework.common.NCLocator;
import nc.bs.gl.reconcilecenter.ReconcileoccursubDMO;
import nc.bs.gl.voucher.VoucherBO;
import nc.bs.logging.Logger;
import nc.gl.utils.GLAssDocVersionUtil;
import nc.gl.utils.NCLangResUtil;
import nc.gl.utils.VoucherDataCenter;
import nc.gl.utils.rate.VoucherAmountConvertor;
import nc.itf.bd.pub.IBDMetaDataIDConst;
import nc.itf.fi.pub.UFDateTools;
import nc.itf.gl.pub.IFreevaluePub;
import nc.itf.gl.pub.ITransferHistoryPrv;
import nc.itf.gl.voucher.IVoucher;
import nc.itf.glcom.para.GLParaAccessor;
import nc.itf.glcom.para.GLParaValueConst;
import nc.itf.org.IOrgConst;
import nc.itf.org.IOrgMetaDataIDConst;
import nc.itf.pubbd.profitcenter.IProfitCenterPubService;
import nc.jdbc.framework.processor.ArrayListProcessor;
import nc.login.bs.INCUserQueryService;
import nc.pub.gl.model.BUWithBookRefModel;
import nc.pubitf.accperiod.AccountCalendar;
import nc.pubitf.bd.accessor.GeneralAccessorFactory;
import nc.pubitf.bd.accessor.IGeneralAccessor;
import nc.pubitf.org.cache.IBasicOrgUnitPubService_C;
import nc.pubitf.para.SysInitQuery;
import nc.vo.bd.accessor.IBDData;
import nc.vo.bd.account.AccAssVO;
import nc.vo.bd.account.AccountVO;
import nc.vo.bd.currinfo.CurrinfoVO;
import nc.vo.bd.currinfo.ICurrinfoConst;
import nc.vo.bd.period.AccperiodVO;
import nc.vo.bd.period2.AccperiodmonthVO;
import nc.vo.fip.pub.SqlTools;
import nc.vo.fipub.freevalue.Module;
import nc.vo.fipub.freevalue.account.proxy.AccAssGL;
import nc.vo.fipub.utils.AccountCalendarUtils;
import nc.vo.fipub.utils.StrTools;
import nc.vo.gateway60.accountbook.AccountBookUtil;
import nc.vo.gateway60.accountbook.GlOrgUtils;
import nc.vo.gateway60.itfs.AccountByPkThreadCache;
import nc.vo.gateway60.itfs.AccountUtilGL;
import nc.vo.gateway60.itfs.CalendarUtilGL;
import nc.vo.gateway60.itfs.Currency;
import nc.vo.gateway60.pub.GlBusinessException;
import nc.vo.gl.formulaexecute.GlAssVOTools;
import nc.vo.gl.pubvoucher.DetailVO;
import nc.vo.gl.pubvoucher.OperationResultVO;
import nc.vo.gl.pubvoucher.VoucherKey;
import nc.vo.gl.pubvoucher.VoucherModflagTool;
import nc.vo.gl.pubvoucher.VoucherVO;
import nc.vo.gl.voucher.TallyConditionVO;
import nc.vo.gl.vouchertools.DetailTool;
import nc.vo.gl.vouchertools.XML_VoucherTranslator;
import nc.vo.glcom.ass.AssVO;
import nc.vo.glcom.constant.IGlDataPowerConst;
import nc.vo.glcom.glperiod.GlPeriodVO;
import nc.vo.glcom.inteltool.AppendVO;
import nc.vo.glcom.nodecode.GlNodeConst;
import nc.vo.glcom.tools.CheckSagaStatusUtil;
import nc.vo.glcom.tools.GLPubProxy;
import nc.vo.jcom.lang.StringUtil;
import nc.vo.ml.NCLangRes4VoTransl;
import nc.vo.org.AccountingBookVO;
import nc.vo.org.OrgVO;
import nc.vo.profitcenter.ProfitcenterVersionVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.BusinessRuntimeException;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.lang.UFDate;
import nc.vo.pubapp.util.VOSortUtils;
import nc.vo.pub.lang.UFDateTime;
import nc.vo.pub.lang.UFDouble;
import nc.vo.sm.UserVO;
import nccloud.commons.lang.StringUtils;
import nccloud.dto.gl.lightgl.VoucherDetailMDVO;
import nccloud.dto.gl.lightgl.VoucherMDVO;
import nccloud.dto.gl.lightgl.VoucherWebVO;
import nccloud.pubimpl.gl.lightgl.voucher.validate.PermissionCheckValidate;
import nccloud.pubimpl.gl.lightgl.voucher.validate.TempSaveValidate;
import nccloud.pubimpl.gl.lightgl.voucher.validate.VoucherAbandonValidate;
import nccloud.pubimpl.gl.lightgl.voucher.validate.VoucherSaveValidate;
import nccloud.pubimpl.gl.lightgl.voucher.validate.VoucherSignValidate;
import nccloud.pubimpl.gl.lightgl.voucher.validate.VoucherTallyValidate;
import nccloud.pubimpl.gl.lightgl.voucher.validate.VoucherUnAbandonValidate;
import nccloud.pubimpl.gl.lightgl.voucher.validate.VoucherUnCheckValidate;
import nccloud.pubimpl.gl.lightgl.voucher.validate.VoucherUnSignValidate;
import nccloud.pubimpl.gl.lightgl.voucher.validate.VoucherUnTallyValidate;
import nccloud.pubimpl.gl.lightgl.voucher.validate.VouhcerCheckValidate;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

public class VoucherWebBO {

	/**
	 * 保存凭证
	 */
	public Map<String, Object> saveVoucher(VoucherVO voucherVO, boolean isAdd, UFDate busidate)
			throws BusinessException {
		if (voucherVO == null){
			return null;}
		resetVoucherAssid(voucherVO);
		if(StringUtils.isEmpty(voucherVO.getPk_prepared())) {
			voucherVO.setPk_prepared(InvocationInfoProxy.getInstance().getUserId());
		}
		new VoucherSaveValidate().validate(voucherVO);
		setDefaultValue(voucherVO);

		// 暂存凭证保存时，自动保存为正常凭证
		voucherVO.setTempsaveflag(UFBoolean.FALSE);
		Set<String> accasoas=new HashSet<String>();
		Object[] details = voucherVO.getDetail().toArray();
		for (Object detailvo : details) {
			DetailVO detail=(DetailVO) detailvo;
			detail.setTempsaveflag(UFBoolean.FALSE);
			accasoas.add(detail.getPk_accasoa());
		}
		processErrMsg(voucherVO);
		OperationResultVO[] results = NCLocator.getInstance().lookup(IVoucher.class).save(voucherVO, Boolean.TRUE);
		Map<String, Object> voucherMap = getResultMap(results,voucherVO);
		VoucherVO[] sort =new VoucherVO[1];
		sort[0]=voucherVO;
		SortDetailIndexUtil.sortAfterUpdate(sort);

		Map<String, Object> map = new HashMap<String, Object>();
		// 附属信息
		Map<String, Object> paraInfo = new AccountingbookQryBO().queryBookCombineInfo(voucherVO.getPk_accountingbook(),
				voucherVO.getPrepareddate().toStdString(),true);
		if (isAdd) {
			// 新增保存返回下一张凭证号
			Map<String, Integer> voucherNo = new VoucherWebQryBO().getVoucherNo(voucherVO.getPk_accountingbook(),
					voucherVO.getPrepareddate()==null?busidate:voucherVO.getPrepareddate(), voucherVO.getPk_vouchertype());
			paraInfo.put("next", voucherNo);
		}

		paraInfo.put("isShowNum",voucherMap.get("isShowNum"));

		if(voucherMap.get("success")!=null&&(boolean)paraInfo.get("isVerify")){
			//需要即时核销，寻找第一个核销科目行号
			VoucherMDVO mdvo=(VoucherMDVO) voucherMap.get("success");
			String pk_glorgbook = mdvo.getPk_accountingbook();
			String prepareddate = mdvo.getPrepareddate().toString();
			String[] startAccountPks = GLPubProxy.getRemoteVerifyobj().getAllPk_accasoaOfVerifyObj(new String[] {pk_glorgbook},prepareddate);
			if (startAccountPks!= null && startAccountPks.length > 0){
				paraInfo.put("verifyIndex", getVerifyDetailVO(mdvo,startAccountPks));
			}
		}
		map.put("voucher", voucherMap);
		map.put("paraInfo", paraInfo);

// begin modify by wy at 2025年2月17日 拉取友费控 报销单附件
//		YFKHandlerUtil.YFKAttachToNC65Bill(voucherVO);
// end modify by wy
		return map;
	}

	/**
	 *
	 */
	private void processErrMsg(VoucherVO voucherVO) {
		if(!StrTools.isEmptyStr(voucherVO.getErrmessage())) {return;}
		Object[] details = voucherVO.getDetail().toArray();
		for (Object detailvo : details) {
			DetailVO detail=(DetailVO) detailvo;
			if(detail.getErrmessage() != null) {
				voucherVO.setErrmessage(NCLangResUtil.getInstance().getStrByID("20021005",
						"UPP20021005-000000")/* @res "????" */);
				voucherVO.setErrmessageh(NCLangResUtil.getInstance().getStrByID("20021005",
						"UPP20021005-000000")/* @res "????" */);
				return;
			}
		}

	}

	private int getVerifyDetailVO(VoucherMDVO vo, String[] startAccountPks) {
		for (int i = 0; i < vo.getDetailMDVOs().length; i++) {
			String strDetailAccPK = vo.getDetailMDVOs()[i].getPk_accasoa();
			for (int j = 0; j < startAccountPks.length; j++) {
				if (startAccountPks[j].equals(strDetailAccPK)) {
					return vo.getDetailMDVOs()[i].getDetailindex();
				}
			}
		}
		return -1;
	}

	/**
	 * 暂存凭证
	 */
	public Map<String, Object> tempSaveVoucher(VoucherWebVO voucherWebVO) throws BusinessException {
		if (voucherWebVO == null){
			return null;
		}
		VoucherVO voucherVO = voucherWebVO.toVoucherVO();
		voucherVO.setTempsaveflag(UFBoolean.TRUE);
		setDefaultValue(voucherVO);
		resetVoucherAssid(voucherVO);
		new TempSaveValidate().validate(voucherVO);

		OperationResultVO[] results = NCLocator.getInstance().lookup(IVoucher.class).save(voucherVO, Boolean.FALSE);
		Map<String, Object> voucherMap = getResultMap(results,voucherVO);

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("voucher", voucherMap);
		// 附属信息
		Map<String, Object> paraInfo = new AccountingbookQryBO().queryBookCombineInfo(voucherVO.getPk_accountingbook(),
				voucherVO.getPrepareddate().toStdString(),true);
		paraInfo.put("isShowNum",voucherMap.get("isShowNum"));
		map.put("paraInfo", paraInfo);
		return map;
	}
	/**
	 * 修改前特殊数据权限校验
	 * @param voucher 凭证VO
	 * @return 无权限直接抛出异常,有权限返回true
	 * @throws BusinessException
	 */
	public Map<String, Object> editCheck(VoucherVO voucher) throws BusinessException {

		VoucherVO voucherVO = NCLocator.getInstance().lookup(IVoucher.class).queryByPk(voucher.getPk_voucher());
		if(voucherVO==null){
			throw new BusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("20021005", "UPP20021005-000538")/*
			 * @res "凭证已被他人删除，请刷新数据。"
			 */);
		}
		String operateCode = IGlDataPowerConst.OPERATE_EDIT;
		//系统用户不校验特殊数据权限
		if(!"NC_USER0000000000000".equals(InvocationInfoProxy.getInstance().getUserId())) {
			String errMessage = new PermissionCheckValidate().checkSpecialDataValidate(new VoucherVO[]{voucherVO},
					operateCode);
			if(!StringUtil.isEmptyWithTrim(errMessage)){
				throw new BusinessException(errMessage);
			}
		}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("havePerm", true);
		return map;
	}
	/**
	 * 保存标错
	 */
	public Map<String, Object> saveError(VoucherWebVO voucherWebVO) throws BusinessException {
		if (voucherWebVO == null){
			return null;}

		VoucherVO voucherVO = voucherWebVO.toVoucherVO();
		if(StringUtil.isEmptyWithTrim(voucherVO.getPeriod())){
			//传参容错
			UFDate prepareddate = voucherVO.getPrepareddate();
			AccountCalendar calendar = CalendarUtilGL.getAccountCalendarByAccountBook(voucherVO.getPk_accountingbook());
			calendar.setDate(prepareddate);
			voucherVO.setYear(calendar.getYearVO().getPeriodyear());
			voucherVO.setPeriod(calendar.getMonthVO().getAccperiodmth());

			if(StringUtil.isEmptyWithTrim(voucherVO.getM_adjustperiod())){
				voucherVO.setM_adjustperiod(voucherVO.getPeriod());
			}else if(voucherVO.getM_adjustperiod().length()>3&&voucherVO.getM_adjustperiod().contains("-")){
				voucherVO.setM_adjustperiod(voucherVO.getM_adjustperiod().split("-")[1]);
			}
		}
//		if (StrTools.isEmptyStr(voucherVO.getErrmessage())) {
//			voucherVO.setErrmessage(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("20021005",
//					"UPP20021005-000000")/* @res "错误" */);
//			voucherVO.setErrmessageh(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("20021005",
//					"UPP20021005-000000")/* @res "错误" */);
//		}
		// 这个只返回成功的result，错误的全部抛出来了。所以不需要像新增保存判断结果中result了
		voucherVO.setErrmessageh(voucherVO.getErrmessage());
//		if(!StringUtil.isEmptyWithTrim(voucherVO.getErrmessage())) {
//			byte[] b =voucherVO.getErrmessage().getBytes();
//			if(b.length>60) {
//				throw new BusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("20021005",
//						"UPP20021005-000741")/* @res "错误信息太长。"*/);
//			}
//		}

//		if(voucherVO.getDetails()!=null) {
//			DetailVO[] details=voucherVO.getDetails();
//			for(DetailVO detail:details) {
//				if(!StringUtil.isEmptyWithTrim(detail.getErrmessage())) {
//					byte[] b =detail.getErrmessage().getBytes();
//					if(b.length>90) {
//						throw new BusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("20021005",
//								"UPP20021005-000741")/* @res "错误信息太长。"*/);
//					}
//				}
//			}
//		}
		GLPubProxy.getRemoteVoucher().saveError(voucherVO);
		VoucherVO newVO = NCLocator.getInstance().lookup(IVoucher.class).queryByPk(voucherVO.getPk_voucher());
		VoucherMDVO mdvo = new VoucherMDVO(newVO,true);
		Map<String, Object> map = new VoucherWebQryBO().transVoucher(mdvo);
//		mdvo = transVoucherVO(newVO);
//		Map<String, Object> map = new HashMap<String, Object>();
//		map.put("voucher", mdvo);
//
//		Map<String, Object> paraInfo = new AccountingbookQryBO().queryBookCombineInfo(voucherVO.getPk_accountingbook(),
//				voucherVO.getPrepareddate().toStdString(), true);
//		paraInfo.put("isShowNum",voucherMap.get("isShowNum"));
//		map.put("paraInfo", paraInfo);
		return map;
	}

	/**
	 * 删除
	 */
	public Map<String,Object> deleteVoucher(String[] pk_vouchers) throws BusinessException {
		if(pk_vouchers==null||pk_vouchers.length==0){
			return null;}

		VoucherVO[] vouchervos = NCLocator.getInstance().lookup(IVoucher.class).queryByPks(pk_vouchers);
		if(vouchervos==null||vouchervos.length==0){
			throw new BusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("20021005", "UPP20021005-000538")/*
			 * @res "凭证已被他人删除，请刷新数据。"
			 */);
		}
		StringBuffer checkMsg=new StringBuffer();
//		String errMessage = new PermissionCheckValidate().checkSpecialDataValidate(vouchervos,
//				IGlDataPowerConst.OPERATE_DEL);
//		if (!StringUtil.isEmptyWithTrim(errMessage)) {
//			checkMsg.append(errMessage);
//		}

		if(checkMsg.length()>0){
			throw new BusinessException(checkMsg.toString());}
		//删除时也会删除回冲的凭证
		String[] offPks = NCLocator.getInstance().lookup(ITransferHistoryPrv.class).queryWriteoffVouchers(pk_vouchers);
		OperationResultVO[] results = NCLocator.getInstance().lookup(IVoucher.class)
				.deleteByPks(pk_vouchers, InvocationInfoProxy.getInstance().getUserId());
		if (results != null && results.length > 0) {
			OperationResultVO result = results[0];
			if (OperationResultVO.ERROR == result.m_intSuccess) {
				throw new BusinessException(result.m_strDescription);
			}
		}
//			}else{
//				Map<String,Object> map=new HashMap<String,Object>();
//				if(OperationResultVO.WARN==result.m_intSuccess){
//					map.put("warn", result.m_strDescription);
//				}
//				List<String> successPks=new ArrayList<String>();
//				for (OperationResultVO res : results) {
//					successPks.add(res.m_strPK);
//				}
//				//删除时也会删除回冲的凭证
//				String[] offPks = NCLocator.getInstance().lookup(ITransferHistoryPrv.class).queryWriteoffVouchers(successPks.toArray(new String[0]));
//				successPks.addAll(Arrays.asList(offPks));
//				if (successPks.size() > 0)
//					ImageServiceUtil.deleteImageOnSync(successPks.toArray(new String[0]), InvocationInfoProxy
//							.getInstance().getUserId(), "凭证删除时自动删除影像");
//				map.put("success", successPks);
//				return map;
//			}
//		}else{
		//全部成功
		Map<String,Object> map=new HashMap<String,Object>();
		Set<String> successPks=new HashSet<String>();
//			String[] offPks = NCLocator.getInstance().lookup(ITransferHistoryPrv.class).queryWriteoffVouchers(pk_vouchers);
		successPks.addAll(Arrays.asList(pk_vouchers));
		successPks.addAll(Arrays.asList(offPks));
		map.put("success", successPks);
		return map;
//		}
//		return null;
	}
	/**
	 * 复制凭证
	 */
	public Map<String, Object> copyVoucher(VoucherVO voucher,String busidate,boolean isPareddatechange) throws BusinessException {

//		VoucherVO voucher = NCLocator.getInstance().lookup(IVoucher.class).queryByPk(pk_voucher);
//		if(voucher==null){
//			throw new BusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("20021005", "UPP20021005-000646")/* @res "凭证已被删除。" */);}
		VoucherVO vo = (VoucherVO) voucher.clone();
		String oldpreparedate=vo.getPrepareddate().toString();
		if(!isPareddatechange) {
			vo.setPk_voucher(null);
			vo.setPk_casher(null);
			vo.setPk_checked(null);
			vo.setCheckeddate(null);
			vo.setPk_manager(null);
			vo.setPk_prepared(InvocationInfoProxy.getInstance().getUserId());
			vo.setPk_system("GL");
			vo.setSystemname(NCLangResUtil.getInstance().getStrByID("20021005", "UPP20021005-000244")/*总账*/);
			vo.setCashername(null);
			vo.setCheckedname(null);
			vo.setManagername(null);
			vo.setDiscardflag(UFBoolean.FALSE);
			vo.setErrmessage(null);
			vo.setModifyflag("YYY");
			vo.setDetailmodflag(UFBoolean.TRUE);
			vo.setIsmatched( Boolean.valueOf(false));
			vo.setErrmessageh(null);
			vo.setHasCashflowModified(false);
			vo.setPrepareddate(new UFDate(new UFDateTime(busidate).getMillis()));
			vo.setTempsaveflag(UFBoolean.FALSE);
			vo.setCreator(InvocationInfoProxy.getInstance().getUserId());
			vo.setCreationtime(new UFDateTime(InvocationInfoProxy.getInstance().getBizDateTime()));
			vo.setModifier(null);
			vo.setModifiedtime(null);
			vo.setDeleteclass(null);
			vo.setIsOffer(UFBoolean.FALSE);
			vo.setOffervoucher(null);
			vo.setModifyflag(null);
			vo.setSigndate(null);
			vo.setTallydate(null);
			vo.setCheckeddate(null);
			vo.setOffervoucher(null);
			vo.setOfferdate(null);//冲销日期
			vo.setOfferperiod(null);//冲销期间
			if (voucher.getVoucherkind() != null && voucher.getVoucherkind().intValue() == 1) {
				vo.setPrepareddate(voucher.getPrepareddate());
				vo.setYear(voucher.getYear());
				vo.setPeriod(voucher.getPeriod());
				vo.setM_adjustperiod(voucher.getM_adjustperiod());
				vo.setModifyflag("NYY");
			} else {
				vo.setVoucherkind(0);
			}
		}

		AccountCalendar calendar = CalendarUtilGL.getAccountCalendarByAccountBook(voucher.getPk_accountingbook());
		calendar.setDate(vo.getPrepareddate() == null ? new UFDate() : vo.getPrepareddate());
		AccperiodmonthVO monthVO = calendar.getMonthVO();
		if (monthVO != null) {
			String yearmth = monthVO.getYearmth();
			vo.setYear(yearmth.split("-")[0]);
			vo.setPeriod(yearmth.split("-")[1]);
		} else {
			vo.setYear(AccountCalendarUtils.getCurrentYear());
			vo.setPeriod(AccountCalendarUtils.getCurrentMonth());
		}

		if (voucher.getVoucherkind() == null || voucher.getVoucherkind().intValue() != 1) {
			vo.setM_adjustperiod(vo.getPeriod());
		}

		if(!isPareddatechange) {
			vo.setNo(GLPubProxy.getRemoteVoucher().getCorrectVoucherNo(vo));
			vo.setPk_sourcepk(null);
			vo.setConvertflag(UFBoolean.FALSE);
			vo.setUserData(null);
		}
		String[] pk_units = new String[vo.getNumDetails() + 1];
		Set<String> liabicenters = new HashSet<String>();
		DetailVO detailTemp = null;
		int i = 0;
//		Map<String,String> assMap=new HashMap<String,String>();
		for (i = 0; i < vo.getNumDetails(); i++) {
			detailTemp = vo.getDetail(i);
			if(!isPareddatechange){
				detailTemp.setPk_detail(null);
				detailTemp.setPk_voucher(null);
				detailTemp.setErrmessage(null);
				detailTemp.setModifyflag(VoucherModflagTool.DEFAULT_DETAIL_CTRL);
				detailTemp.setIsmatched(UFBoolean.FALSE);
				detailTemp.setUserData(null);
				detailTemp.setPk_offerdetail(null);
				detailTemp.setVerifyno(null);
				detailTemp.setOtheruserdata(null);
				detailTemp.setBusireconno(null);
				detailTemp.setInnerbusno(null);
				detailTemp.setTempsaveflag(UFBoolean.FALSE);
				detailTemp.setPk_sourcepk(null);
				detailTemp.setVoucherkind(0);
				detailTemp.setPk_system("GL");
			}
			detailTemp.setVerifydate(vo.getPrepareddate().toString());
			detailTemp.setPrepareddate(vo.getPrepareddate());
			if(!StringUtils.isEmpty(detailTemp.getPk_liabilitycenter())) {
				liabicenters.add(detailTemp.getPk_liabilitycenter());
			}
			// 根据制单日期，重新计算汇率和本币
//			resetRateAndLocAmout(vo,detailTemp);
			pk_units[i] = detailTemp.getPk_unit();

			// 根据科目版本清空复制时辅助核算
			if(StringUtil.isEmptyWithTrim(detailTemp.getPk_accasoa())){
				continue;
			}
			AccountVO newAccountVo = AccountByPkThreadCache.getInstance().getAccountVO(
					detailTemp.getPk_accasoa(), vo.getPrepareddate().toString());
			if (newAccountVo == null) {
				AccountVO oldaccvo = AccountByPkThreadCache.getInstance().getAccountVO(
						detailTemp.getPk_accasoa(), oldpreparedate);
				if(oldaccvo!=null) {
					newAccountVo=AccountByPkThreadCache.getInstance().
							getAccountVOByCode(vo.getPk_accountingbook(), oldaccvo.getCode(), vo.getPrepareddate().toString());
//					detailTemp.setPk_accasoa(newAccountVo.getPk_accasoa());
				}
//				throw new GlBusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes()
//						.getStrByID("20021005", "UPP20021005-000582")/*
//																	 * @res
//																	 * "科目信息有错！"
//																	 */);
			}
			if (newAccountVo == null) {
				detailTemp.setPk_accasoa(null);
				detailTemp.setAss(null);
				detailTemp.setAssid(null);
			}else {
				detailTemp.setPk_accasoa(newAccountVo.getPk_accasoa());
				AccAssVO[] accAssVOs = newAccountVo.getAccass();
				AssVO[] newAssVOs = getNewAssVOs(accAssVOs, detailTemp.getAss());
				if (newAssVOs == null) {
					detailTemp.setAss(null);
					detailTemp.setAssid(null);
				} else {
					if (!GlAssVOTools.isAssVOMatched(detailTemp.getAss(), newAssVOs)) {
						String assid = null;
						try {
							assid = NCLocator.getInstance().lookup(IFreevaluePub.class)
									.getAssID(newAssVOs, true, vo.getPk_group(), Module.GL);
//							newAssVOs = NCLocator.getInstance().lookup(IFreevaluePub.class).queryAssvosByid(assid, Module.GL);
//							String assname = ShowContentCenter.getShowAss(vo.getPk_accountingbook(), newAssVOs);
//							assMap.put(assid, assname);
						} catch (BusinessException e) {
							Logger.error(e.getMessage(), e);
						}
						detailTemp.setAssid(assid);
					}
					detailTemp.setAss(newAssVOs);
				}
			}
		}
		if (vo.getPk_org() == null) {
			vo.setPk_org(AccountBookUtil.getPk_orgByAccountBookPk(vo.getPk_accountingbook()));
		}
		pk_units[i] = vo.getPk_org();
		HashMap<String, String> versionMap = null;
		if (vo.getPk_org() != null) {
			try {
				versionMap = GlOrgUtils.getNewVIDSByOrgIDSAndDate(pk_units, vo.getPrepareddate());
			} catch (BusinessException e) {
				Logger.error(e.getMessage(), e);
			}
		}
		Map<String, ProfitcenterVersionVO> liabVersionMap=null;
		if (liabicenters.size() > 0) {
			liabVersionMap = NCLocator.getInstance()
					.lookup(IProfitCenterPubService.class)
					.queryVersion(liabicenters.toArray(new String[0]), vo.getPrepareddate());
		}
		if (versionMap != null||liabVersionMap!=null) {
			if(versionMap != null) {
				vo.setPk_org_v(versionMap.get(vo.getPk_org()));
			}
			for (DetailVO detail : vo.getDetails()) {
				if(versionMap != null) {
					detail.setPk_unit_v(versionMap.get(detail.getPk_unit()));
				}
				if(liabVersionMap!=null) {
					ProfitcenterVersionVO versionvo = liabVersionMap.get(detail.getPk_liabilitycenter());
					if(versionvo!=null) {
						detail.setPk_liabilitycenter_v(versionvo.getPk_vid());
					}
				}
			}
		}
		//辅助核算档案多版本
		GLAssDocVersionUtil.adjustAssDocVName(vo.getDetails(), VoucherKey.D_ASS, VoucherKey.V_PREPAREDDATE, null);
		new VoucherAmountConvertor(vo).convert();
		VoucherMDVO mdvo=new VoucherMDVO(vo,true);
		Map<String, Object> map = new VoucherWebQryBO().transVoucher(mdvo);
		return map;
	}

	/**
	 * 复制凭证
	 */
	public Map<String, Object> copyVoucher(VoucherVO voucher,String busidate) throws BusinessException {

//		VoucherVO voucher = NCLocator.getInstance().lookup(IVoucher.class).queryByPk(pk_voucher);
//		if(voucher==null){
//			throw new BusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("20021005", "UPP20021005-000646")/* @res "凭证已被删除。" */);}
		VoucherVO vo = (VoucherVO) voucher.clone();
		String oldpreparedate=vo.getPrepareddate().toString();
		//if(!isPareddatechange) {
		vo.setPk_voucher(null);
		vo.setPk_casher(null);
		vo.setPk_checked(null);
		vo.setCheckeddate(null);
		vo.setPk_manager(null);
		vo.setPk_prepared(InvocationInfoProxy.getInstance().getUserId());
		vo.setPk_system("GL");
		vo.setSystemname(NCLangResUtil.getInstance().getStrByID("20021005", "UPP20021005-000244")/*????*/);
		vo.setCashername(null);
		vo.setCheckedname(null);
		vo.setManagername(null);
		vo.setDiscardflag(UFBoolean.FALSE);
		vo.setErrmessage(null);
		vo.setModifyflag("YYY");
		vo.setDetailmodflag(UFBoolean.TRUE);
		vo.setIsmatched( Boolean.valueOf(false));
		vo.setErrmessageh(null);
		vo.setHasCashflowModified(false);
		vo.setPrepareddate(new UFDate(new UFDateTime(busidate).getMillis()));
		vo.setTempsaveflag(UFBoolean.FALSE);
		vo.setCreator(InvocationInfoProxy.getInstance().getUserId());
		vo.setCreationtime(new UFDateTime(InvocationInfoProxy.getInstance().getBizDateTime()));
		vo.setModifier(null);
		vo.setModifiedtime(null);
		vo.setDeleteclass(null);
		vo.setIsOffer(UFBoolean.FALSE);
		vo.setOffervoucher(null);
		vo.setModifyflag(null);
		vo.setSigndate(null);
		vo.setTallydate(null);
		vo.setCheckeddate(null);
		vo.setOffervoucher(null);
		vo.setOfferdate(null);//????????
		vo.setOfferperiod(null);//???????
		if (voucher.getVoucherkind() != null && voucher.getVoucherkind().intValue() == 1) {
			vo.setPrepareddate(voucher.getPrepareddate());
			vo.setYear(voucher.getYear());
			vo.setPeriod(voucher.getPeriod());
			vo.setM_adjustperiod(voucher.getM_adjustperiod());
			vo.setModifyflag("NYY");
		} else {
			vo.setVoucherkind(0);
		}
		//}

		AccountCalendar calendar = CalendarUtilGL.getAccountCalendarByAccountBook(voucher.getPk_accountingbook());
		calendar.setDate(vo.getPrepareddate() == null ? new UFDate() : vo.getPrepareddate());
		AccperiodmonthVO monthVO = calendar.getMonthVO();
		if (monthVO != null) {
			String yearmth = monthVO.getYearmth();
			vo.setYear(yearmth.split("-")[0]);
			vo.setPeriod(yearmth.split("-")[1]);
		} else {
			vo.setYear(AccountCalendarUtils.getCurrentYear());
			vo.setPeriod(AccountCalendarUtils.getCurrentMonth());
		}

		if (voucher.getVoucherkind() == null || voucher.getVoucherkind().intValue() != 1) {
			vo.setM_adjustperiod(vo.getPeriod());
		}

		//if(!isPareddatechange) {
		vo.setNo(GLPubProxy.getRemoteVoucher().getCorrectVoucherNo(vo));
		vo.setPk_sourcepk(null);
		vo.setConvertflag(UFBoolean.FALSE);
		vo.setUserData(null);
		//}
		String[] pk_units = new String[vo.getNumDetails() + 1];
		Set<String> liabicenters = new HashSet<String>();
		DetailVO detailTemp = null;
		int i = 0;
//		Map<String,String> assMap=new HashMap<String,String>();
		for (i = 0; i < vo.getNumDetails(); i++) {
			detailTemp = vo.getDetail(i);
			//if(!isPareddatechange){
			detailTemp.setPk_detail(null);
			detailTemp.setPk_voucher(null);
			detailTemp.setErrmessage(null);
			detailTemp.setModifyflag(VoucherModflagTool.DEFAULT_DETAIL_CTRL);
			detailTemp.setIsmatched(UFBoolean.FALSE);
			detailTemp.setUserData(null);
			detailTemp.setPk_offerdetail(null);
			detailTemp.setVerifyno(null);
			detailTemp.setOtheruserdata(null);
			detailTemp.setBusireconno(null);
			detailTemp.setInnerbusno(null);
			detailTemp.setTempsaveflag(UFBoolean.FALSE);
			detailTemp.setPk_sourcepk(null);
			detailTemp.setVoucherkind(0);
			detailTemp.setPk_system("GL");
			//}
			detailTemp.setVerifydate(vo.getPrepareddate().toString());
			detailTemp.setPrepareddate(vo.getPrepareddate());
			if(!StringUtils.isEmpty(detailTemp.getPk_liabilitycenter())) {
				liabicenters.add(detailTemp.getPk_liabilitycenter());
			}
			// 根据制单日期，重新计算汇率和本币
//			resetRateAndLocAmout(vo,detailTemp);
			pk_units[i] = detailTemp.getPk_unit();

			// 根据科目版本清空复制时辅助核算
			if(StringUtil.isEmptyWithTrim(detailTemp.getPk_accasoa())){
				continue;
			}
			AccountVO newAccountVo = AccountByPkThreadCache.getInstance().getAccountVO(
					detailTemp.getPk_accasoa(), vo.getPrepareddate().toString());
			if (newAccountVo == null) {
				AccountVO oldaccvo = AccountByPkThreadCache.getInstance().getAccountVO(
						detailTemp.getPk_accasoa(), oldpreparedate);
				if(oldaccvo!=null) {
					newAccountVo=AccountByPkThreadCache.getInstance().
							getAccountVOByCode(vo.getPk_accountingbook(), oldaccvo.getCode(), vo.getPrepareddate().toString());
//					detailTemp.setPk_accasoa(newAccountVo.getPk_accasoa());
				}
//				throw new GlBusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes()
//						.getStrByID("20021005", "UPP20021005-000582")/*
//																	 * @res
//																	 * "科目信息有错！"
//																	 */);
			}
			if (newAccountVo == null) {
				detailTemp.setPk_accasoa(null);
				detailTemp.setAss(null);
				detailTemp.setAssid(null);
			}else {
				detailTemp.setPk_accasoa(newAccountVo.getPk_accasoa());
				AccAssVO[] accAssVOs = newAccountVo.getAccass();
				AssVO[] newAssVOs = getNewAssVOs(accAssVOs, detailTemp.getAss());
				if (newAssVOs == null) {
					detailTemp.setAss(null);
					detailTemp.setAssid(null);
				} else {
					if (!GlAssVOTools.isAssVOMatched(detailTemp.getAss(), newAssVOs)) {
						String assid = null;
						try {
							assid = NCLocator.getInstance().lookup(IFreevaluePub.class)
									.getAssID(newAssVOs, true, vo.getPk_group(), Module.GL);
//							newAssVOs = NCLocator.getInstance().lookup(IFreevaluePub.class).queryAssvosByid(assid, Module.GL);
//							String assname = ShowContentCenter.getShowAss(vo.getPk_accountingbook(), newAssVOs);
//							assMap.put(assid, assname);
						} catch (BusinessException e) {
							Logger.error(e.getMessage(), e);
						}
						detailTemp.setAssid(assid);
					}
					detailTemp.setAss(newAssVOs);
				}
			}
		}
		if (vo.getPk_org() == null) {
			vo.setPk_org(AccountBookUtil.getPk_orgByAccountBookPk(vo.getPk_accountingbook()));
		}
		pk_units[i] = vo.getPk_org();
		HashMap<String, String> versionMap = null;
		if (vo.getPk_org() != null) {
			try {
				versionMap = GlOrgUtils.getNewVIDSByOrgIDSAndDate(pk_units, vo.getPrepareddate());
			} catch (BusinessException e) {
				Logger.error(e.getMessage(), e);
			}
		}
		Map<String, ProfitcenterVersionVO> liabVersionMap=null;
		if (liabicenters.size() > 0) {
			liabVersionMap = NCLocator.getInstance()
					.lookup(IProfitCenterPubService.class)
					.queryVersion(liabicenters.toArray(new String[0]), vo.getPrepareddate());
		}
		if (versionMap != null||liabVersionMap!=null) {
			if(versionMap != null) {
				vo.setPk_org_v(versionMap.get(vo.getPk_org()));
			}
			for (DetailVO detail : vo.getDetails()) {
				if(versionMap != null) {
					detail.setPk_unit_v(versionMap.get(detail.getPk_unit()));
				}
				if(liabVersionMap!=null) {
					ProfitcenterVersionVO versionvo = liabVersionMap.get(detail.getPk_liabilitycenter());
					if(versionvo!=null) {
						detail.setPk_liabilitycenter_v(versionvo.getPk_vid());
					}
				}
			}
		}
		//辅助核算档案多版本
		GLAssDocVersionUtil.adjustAssDocVName(vo.getDetails(), VoucherKey.D_ASS, VoucherKey.V_PREPAREDDATE, null);
		new VoucherAmountConvertor(vo).convert();
		VoucherMDVO mdvo=new VoucherMDVO(vo,true);
		Map<String, Object> map = new VoucherWebQryBO().transVoucher(mdvo);
		return map;
	}

	/**
	 * 审核
	 */
	public HashMap<String,Object> checkVoucher(String[] pk_vouchers, String[] tss, boolean op,boolean isList)
			throws BusinessException {
		HashMap<String,Object> result = null;
		// ********************add by mzq******************************
//		VoucherVO[] vouchersL = (new VoucherBO()).queryByPks(pk_vouchers, false);
//		String[] tss = new String[vouchersL.length];
//		for(int i=0;i<vouchersL.length;i++) {
//			tss[i] = vouchersL[i].getTs().toLocalString();
//		}
		// ********************add by mzq******************************
		if(op){
			result = new VouhcerCheckValidate().getValidateResult(pk_vouchers, tss);
		}else{
			result = new VoucherUnCheckValidate().getValidateResult(pk_vouchers, tss);
		}
		String[] validatedPks = (String[])result.get("success");
		OperationResultVO[] opResults = null;
		if(validatedPks!=null&&validatedPks.length>0){
			String userid = InvocationInfoProxy.getInstance().getUserId();
			if(InvocationInfoProxy.getInstance().getProperty("operator") != null) {//???????openapi???
				String usercode  = InvocationInfoProxy.getInstance().getProperty("operator");
				UserVO userVO = NCLocator.getInstance().lookup(INCUserQueryService.class).findUserVO(null, usercode);
				if(userVO!=null) {
					userid = userVO.getPrimaryKey();//???????
				}
			}
			opResults = GLPubProxy.getRemoteVoucherAudit().checkVoucherByPks(validatedPks,userid,op);
		}
		HashMap<String,Object> resultMap = getResultMap(opResults,validatedPks,result,isList);
		if(isList) {//
			processResult(resultMap);
		}
		return resultMap;
	}

	/**
	 * 记账
	 */
	public HashMap<String, Object> tallyVoucher(String[] pk_vouchers, String[] tss, String date, boolean op,boolean isList) throws BusinessException {
		CheckSagaStatusUtil.checkSagaStatus("gl_voucher", "pk_voucher", pk_vouchers);
		HashMap<String, Object> result = null;
		// ********************add by mzq******************************
//		VoucherVO[] vouchersL = (new VoucherBO()).queryByPks(pk_vouchers, false);
//		String[] tss = new String[vouchersL.length];
//		for(int i=0;i<vouchersL.length;i++) {
//			tss[i] = vouchersL[i].getTs().toLocalString();
//		}
		// ********************add by mzq******************************
		if (op) {
			result = new VoucherTallyValidate().getValidateResult(pk_vouchers, tss);
		} else {
			result = new VoucherUnTallyValidate().getValidateResult(pk_vouchers, tss);
		}
		pk_vouchers = (String[]) result.get("success");
		String sql = "select distinct pk_accountingbook,year,period from gl_voucher where "
				+ SqlTools.getInStr("pk_voucher", pk_vouchers, true);
		List resultSet = (List) new BaseDAO().executeQuery(sql, new ArrayListProcessor());
		String pk_accountingbook = null;
		String year = null;
		HashSet<String> period = new HashSet<String>();
		if (resultSet.size() > 0) {
			Object[] row = (Object[]) resultSet.get(0);
			pk_accountingbook = row[0].toString();
			year = row[1].toString();
			for (Object obj : resultSet) {
				Object[] eachrow = (Object[]) obj;
				period.add(eachrow[2].toString());
			}
		}
		TallyConditionVO conditionVO = new TallyConditionVO();
		conditionVO.setPk_accountingbook(pk_accountingbook);
		conditionVO.setYear(year);
		conditionVO.setPeriods(period.toArray(new String[0]));
		conditionVO.setStrVoucherPK(pk_vouchers);
		String userid = InvocationInfoProxy.getInstance().getUserId();
		if(InvocationInfoProxy.getInstance().getProperty("operator") != null) {
			String usercode  = InvocationInfoProxy.getInstance().getProperty("operator");
			UserVO userVO = NCLocator.getInstance().lookup(INCUserQueryService.class).findUserVO(null, usercode);
			if(userVO!=null) {
				userid = userVO.getPrimaryKey();
			}
		}
		conditionVO.setStrManager(userid);
		conditionVO.setTallyDate(new UFDate(new UFDateTime(date).getMillis()));
		conditionVO.setOp(UFBoolean.valueOf(op));
		OperationResultVO[] opResults = GLPubProxy.getRemoteVoucherTally().tallyVoucherByPks(conditionVO);
		HashMap<String,Object> resultMap = getResultMap(opResults, pk_vouchers, result,isList);
		processResult(resultMap);
		return resultMap;
	}

	/**
	 * 作废
	 */
	public HashMap<String, Object> abandonVoucher(String[] pk_vouchers, String[] tss, boolean op,boolean isList) throws BusinessException {
		HashMap<String, Object> result = null;
		//校验特殊数据权限
		String operatorCode=IGlDataPowerConst.OPERATE_ABANDON;
		if(!op){
			operatorCode=IGlDataPowerConst.OPERATE_UNABANDON;
		}
		VoucherVO[] vouchervos = NCLocator.getInstance().lookup(IVoucher.class).queryByPks(pk_vouchers);
		if(vouchervos==null||vouchervos.length==0) {
			throw new BusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("20021005", "UPP20021005-000538")/*
			 * @res "凭证已被他人删除，请刷新数据。"
			 */);
		}
		StringBuffer checkMsg=new StringBuffer();
		String errMessage = new PermissionCheckValidate().checkSpecialDataValidate(vouchervos, operatorCode);
		if (!StringUtil.isEmptyWithTrim(errMessage)) {
			checkMsg.append(errMessage);
		}
		if(checkMsg.length()>0){
			throw new BusinessException(checkMsg.toString());}
		// ********************add by mzq******************************
//		VoucherVO[] vouchersL = (new VoucherBO()).queryByPks(pk_vouchers, false);
//		String[] tss = new String[vouchersL.length];
//		for(int i=0;i<vouchersL.length;i++) {
//			tss[i] = vouchersL[i].getTs().toLocalString();
//		}
		// ********************add by mzq******************************
		if (op) {
			result = new VoucherAbandonValidate().getValidateResult(pk_vouchers, tss);
		} else {
			result = new VoucherUnAbandonValidate().getValidateResult(pk_vouchers, tss);
		}
		pk_vouchers = (String[]) result.get("success");
		OperationResultVO[] opResults = null;
		if (pk_vouchers != null && pk_vouchers.length > 0) {
			opResults = GLPubProxy.getRemoteVoucherList().abandonVoucherByPks(pk_vouchers,
					InvocationInfoProxy.getInstance().getUserId(), op);
		}
		HashMap<String,Object> resultMap = getResultMap(opResults, pk_vouchers, result,isList);
		processResult(resultMap);
		return resultMap;
	}

	/**
	 * 签字
	 */
	public HashMap<String, Object> signVoucher(String[] pk_vouchers, String[] tss, String date,boolean op,boolean isList,String bizdate) throws BusinessException {

		HashMap<String, Object> result = null;
		// ********************add by mzq******************************
//		VoucherVO[] vouchersL = (new VoucherBO()).queryByPks(pk_vouchers, false);
//		String[] tss = new String[vouchersL.length];
//		for(int i=0;i<vouchersL.length;i++) {
//			tss[i] = vouchersL[i].getTs().toLocalString();
//		}
		// ********************add by mzq******************************
		if (op) {
			result = new VoucherSignValidate().getValidateResult(pk_vouchers, tss);
		} else {
			result = new VoucherUnSignValidate().getValidateResult(pk_vouchers, tss);
		}
		pk_vouchers = (String[]) result.get("success");
		OperationResultVO[] opResults = null;
		if (pk_vouchers != null && pk_vouchers.length > 0) {
			if(op){
				VoucherVO[] vouchervos = new VoucherBO().queryByPks(pk_vouchers);
				//1=系统日期 2=业务日期 3=手工日期
				List<String> handdate=new ArrayList<String>();
				List<String> busidate=new ArrayList<String>();
				List<String> sysdate=new ArrayList<String>();
				for (VoucherVO voucherVO : vouchervos) {
					String signdateType=SysInitQuery.getParaString(voucherVO.getPk_accountingbook(), "GL088");//hourui-多时区
					if(GLParaValueConst.GL088_SYSTEM_DATE.equals(signdateType)){
						UFDate signdate=new UFDate();
						GlPeriodVO period = getPeriod(voucherVO.getPk_accountingbook(),signdate);
						if(voucherVO.getPrepareddate().toStdString().compareTo(signdate.toStdString())>0){
							Map<String,Object> errMap=(Map<String,Object>) result.get("error");
							errMap.put(voucherVO.getPk_voucher(),  NCLangRes4VoTransl.getNCLangRes().getStrByID("20021005","UPP20021005-000128")/*@res "#签字日期小于制单日期#"*/);
							continue;
						}else if(voucherVO.getYear().compareTo(period.getYear()) != 0 || voucherVO.getPeriod().compareTo(period.getMonth()) != 0){
							Map<String,Object> errMap=(Map<String,Object>) result.get("error");
							errMap.put(voucherVO.getPk_voucher(),  NCLangRes4VoTransl.getNCLangRes().getStrByID("20021005","UPP20021005-000129")/*@res "#签字日期与制单日期不在同一期间#"*/);
							continue;
						}
						sysdate.add(voucherVO.getPk_voucher());
					}else if(GLParaValueConst.GL088_BUSI_DATE.equals(signdateType)){
						UFDate signdate=new UFDate(new UFDateTime(bizdate.substring(0,10)+" 23:59:59").getMillis());
						GlPeriodVO period = getPeriod(voucherVO.getPk_accountingbook(),signdate);
						if(voucherVO.getPrepareddate().toStdString().compareTo(signdate.toStdString())>0){
							Map<String,Object> errMap=(Map<String,Object>) result.get("error");
							errMap.put(voucherVO.getPk_voucher(),  NCLangRes4VoTransl.getNCLangRes().getStrByID("20021005","UPP20021005-000128")/*@res "#签字日期小于制单日期#"*/);
							continue;
						}else if(voucherVO.getYear().compareTo(period.getYear()) != 0 || voucherVO.getPeriod().compareTo(period.getMonth()) != 0){
							Map<String,Object> errMap=(Map<String,Object>) result.get("error");
							errMap.put(voucherVO.getPk_voucher(),  NCLangRes4VoTransl.getNCLangRes().getStrByID("20021005","UPP20021005-000129")/*@res "#签字日期与制单日期不在同一期间#"*/);
							continue;
						}
						busidate.add(voucherVO.getPk_voucher());
					}else if(GLParaValueConst.GL088_BY_HAND.equals(signdateType)){
//						new UFDate(new UFDateTime(m_begindate.toLocalString()+" 23:59:59").getMillis())
						UFDate signdate=new UFDate(new UFDateTime(date.substring(0,10)+" 23:59:59").getMillis());
						GlPeriodVO period = getPeriod(voucherVO.getPk_accountingbook(),signdate);
						if(voucherVO.getPrepareddate().toStdString().compareTo(signdate.toStdString())>0){
							Map<String,Object> errMap=(Map<String,Object>) result.get("error");
							errMap.put(voucherVO.getPk_voucher(),  NCLangRes4VoTransl.getNCLangRes().getStrByID("20021005","UPP20021005-000128")/*@res "#签字日期小于制单日期#"*/);
							continue;
						}else if(voucherVO.getYear().compareTo(period.getYear()) != 0 || voucherVO.getPeriod().compareTo(period.getMonth()) != 0){
							Map<String,Object> errMap=(Map<String,Object>) result.get("error");
							errMap.put(voucherVO.getPk_voucher(),  NCLangRes4VoTransl.getNCLangRes().getStrByID("20021005","UPP20021005-000129")/*@res "#签字日期与制单日期不在同一期间#"*/);
							continue;
						}
						handdate.add(voucherVO.getPk_voucher());
					}
				}
				Map<String,OperationResultVO> resultMap=new HashMap<String,OperationResultVO>();
				if(sysdate.size()>0){
					String userid = InvocationInfoProxy.getInstance().getUserId();
					if(InvocationInfoProxy.getInstance().getProperty("operator") != null) {
						String usercode  = InvocationInfoProxy.getInstance().getProperty("operator");
						UserVO userVO = NCLocator.getInstance().lookup(INCUserQueryService.class).findUserVO(null, usercode);
						if(userVO!=null) {
							userid = userVO.getPrimaryKey();
						}
					}
					OperationResultVO[] sysdateRes = GLPubProxy.getRemoteVoucherSign().signVoucherByPks(sysdate.toArray(new String[0]),userid,new UFDate(), op);
					if (sysdateRes != null) {
						for (OperationResultVO res : sysdateRes) {
							resultMap.put(res.m_strPK, res);
						}
					}
				}
				if(busidate.size()>0){
					OperationResultVO[] busidateRes = GLPubProxy.getRemoteVoucherSign().signVoucherByPks(busidate.toArray(new String[0]),
							InvocationInfoProxy.getInstance().getUserId(),
							new UFDate(bizdate), op);
					if (busidateRes != null) {
						for (OperationResultVO res : busidateRes) {
							resultMap.put(res.m_strPK, res);
						}
					}
				}
				if(handdate.size()>0){
					OperationResultVO[] handdateRes = GLPubProxy.getRemoteVoucherSign().signVoucherByPks(handdate.toArray(new String[0]),
							InvocationInfoProxy.getInstance().getUserId(),
							new UFDate(date), op);
					if (handdateRes != null) {
						for (OperationResultVO res : handdateRes) {
							resultMap.put(res.m_strPK, res);
						}
					}
				}
				if(resultMap.size()>0){
					List<OperationResultVO> results=new ArrayList<OperationResultVO>();
					for(String pk_voucher:pk_vouchers){
						results.add(resultMap.get(pk_voucher));
					}
					opResults=results.toArray(new OperationResultVO[0]);
				}
			}else{
				opResults = GLPubProxy.getRemoteVoucherSign().signVoucherByPks(pk_vouchers,
						InvocationInfoProxy.getInstance().getUserId(),
						new UFDate(date), op);
			}

		}
		HashMap<String,Object> resultMap = getResultMap(opResults, pk_vouchers, result,isList);
		processResult(resultMap);
		return resultMap;
	}

	public GlPeriodVO getPeriod(String pk_accountingbook,UFDate date){
		GlPeriodVO glperiod = new GlPeriodVO();
		AccperiodmonthVO month = null;
		AccperiodVO accperiod = null;
		AccountCalendar calendar = null;
		try {
			calendar = CalendarUtilGL.getAccountCalendarByAccountBook(pk_accountingbook);
			accperiod = AccperiodAccessor.getInstance().queryAccperiodVOByDate(
					AccountBookUtil.getAccPeriodSchemePKByAccountingbookPk(pk_accountingbook),
					date == null ? new UFDate(InvocationInfoProxy.getInstance().getBizDateTime()) : date);

			if (accperiod == null) {
				throw new BusinessRuntimeException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("2002GL502",
						"UPP2002GL502-000002")/* @res "取会计期间出错" */);
			}

			glperiod.setYear(accperiod.getPeriodyear());
			glperiod.setYearStartDay(accperiod.getBegindate());
			glperiod.setYearEndDay(accperiod.getEnddate());
			if (date != null) {
				calendar.setDate(date);
			}
			month = calendar.getMonthVO() == null ? new AccperiodmonthVO() : (calendar.getMonthVO());
			glperiod.setMonth(month.getAccperiodmth());
			glperiod.setMonthStartDay(month.getBegindate());
			glperiod.setMonthEndDay(month.getEnddate());
		} catch (Exception e) {
			Logger.error(e.getMessage(), e);
			throw new BusinessRuntimeException(e.getMessage(), e);
		}
		return glperiod;
	}

	/**
	 * 汇总显示
	 */
	public VoucherMDVO showSumDetail(String pk_voucher) throws BusinessException {
		//先将凭证查询出来
		VoucherVO voucher = NCLocator.getInstance().lookup(IVoucher.class).queryByPk(pk_voucher);
		if(voucher==null) {
			throw new BusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("20021005", "UPP20021005-000538")/*
			 * @res "凭证已被他人删除，请刷新数据。"
			 */);
		}
		DetailVO[] details = voucher.getDetails();
		Set<String> accasoas=new HashSet<String>();
		for (int i = 0; i < details.length; i++) {
			accasoas.add(details[i].getPk_accasoa());
		}
		AccountVO[] accountVOs = AccountUtilGL.queryAccountVosByPks(accasoas.toArray(new String[0]), voucher
				.getPrepareddate().toStdString());
		Map<String,AccountVO> accountMap=new HashMap<String,AccountVO>();
		if(accountVOs != null){
			for (AccountVO accountVO : accountVOs) {
				accountMap.put(accountVO.getPk_accasoa(), accountVO);
			}
		}

		int[] subjlevelscheme = AccountUtilGL.getLevelScheme(voucher.getPk_accountingbook());

		List<String> subjcode_sequence=new ArrayList<String>();
		List<DetailVO> nosumdetails=new ArrayList<DetailVO>();
		List<DetailVO> detailsvec=new ArrayList<DetailVO>();
		for (DetailVO detail : details) {
			AccountVO accountVO = accountMap.get(detail.getPk_accasoa());
			Integer subjsumlev = accountVO.getSumprint_level();//汇总打印级次
			int m_printsubjlevel = subjsumlev == 0 ? 100 : subjsumlev.intValue();
			m_printsubjlevel = (m_printsubjlevel == 0 ? 100 : m_printsubjlevel);
			if(m_printsubjlevel == -1){
				nosumdetails.add((DetailVO) detail.clone());
				if (!subjcode_sequence.contains(accountVO.getCode())) {
					subjcode_sequence.add(accountVO.getCode());
				}
				continue;
			}
			int iSubjcodeLength = 0;
			for (int j = 0; j < m_printsubjlevel && j < subjlevelscheme.length; j++)
			{
				iSubjcodeLength = iSubjcodeLength + subjlevelscheme[j];
			}
			if (detail.getUserData() instanceof AppendVO){
				detail.setUserData(null);}

			if (accountVO.getCode().length() >= iSubjcodeLength) {
				String tmpsubjcode =VoucherDataCenter.getAccsubjByPK(voucher.getPk_accountingbook(), detail.getPk_accasoa(), voucher.getPrepareddate().toStdString()).getCode().substring(0, iSubjcodeLength);
				AccountVO tmpsubjvo = VoucherDataCenter.getAccsubjByCode(voucher.getPk_accountingbook(), tmpsubjcode, voucher.getPrepareddate().toStdString());
				detail.setPk_accasoa(tmpsubjvo.getPk_accasoa());
				detail.setAccsubjcode(tmpsubjvo.getCode());
				detail.setAccsubjname(tmpsubjvo.getName());
				if (!subjcode_sequence.contains(tmpsubjvo.getCode())) {
					subjcode_sequence.add(tmpsubjvo.getCode());
				}
			}else{
				if(!subjcode_sequence.contains(accountVO.getCode())){
					subjcode_sequence.add(accountVO.getCode());
				}
			}

			Vector<AccAssVO> subjass = AccAssGL.getAccAssVOsByAccount(voucher.getPk_accountingbook(), accountVO);
			if (subjass != null && subjass.size() > 0) {
				String tassid = "";
				List<AssVO> tassvos = new ArrayList<AssVO>();
				for (AccAssVO subjassvo : subjass) {
					boolean hasfind = false;
					AssVO[] assvos = detail.getAss();
					if (assvos != null) {
						for (AssVO assVO : assvos) {
							if (subjassvo.getPk_entity().equals(assVO.getPk_Checktype())) {
								tassid = tassid + assVO.getPk_Checktype() + assVO.getPk_Checkvalue();
								tassvos.add(assVO);
								hasfind = true;
								break;
							}
						}
					}
				}

				if (tassvos.size() > 0)
				{
					detail.setAssid(tassid);
					AssVO[] newAss = tassvos.toArray(new AssVO[0]).clone();
					detail.setAss(newAss);
				}
				else
				{
					detail.setAssid(null);
					detail.setAss(null);
				}

				String tmpassid = "";
				List<AssVO> tmpassvos = new ArrayList<AssVO>();
				for (AccAssVO subjassvo : subjass) {
					if (subjassvo.getIssumprint().booleanValue()) {
						AssVO[] assvos = detail.getAss();
						if (assvos != null) {
							for (AssVO assVO : assvos) {
								if (subjassvo.getPk_entity().equals(assVO.getPk_Checktype())) {
									tmpassid = tmpassid + assVO.getPk_Checktype() + assVO.getPk_Checkvalue();
									tmpassvos.add(assVO);
									break;
								}
							}
						}
					}
				}

				if (tmpassvos.size() > 0)
				{
					detail.setAssid(tmpassid);
					AssVO[] newAss = tmpassvos.toArray(new AssVO[0]).clone();
					detail.setAss(newAss);
				}
				else
				{
					detail.setAssid("null");
					detail.setAss(null);
				}
			} else {
				detail.setAssid("null");
				detail.setAss(null);
			}
			detailsvec.add(detail);
		}

		DetailVO[] tmpdebit = detailsvec.toArray(new DetailVO[0]).clone();
		int[] intSortIndex = new int[] { VoucherKey.D_PK_ACCSUBJ, VoucherKey.D_PK_CURRTYPE, VoucherKey.D_ASSID,
				VoucherKey.D_DIRECTION };
		// start edit by aden 2023-05-15 14:01:37
		// YYZK010 凭证汇总显示方式（1： 会计科目，2： 摘要+会计科目）
		String[] orgs = AccountingBookQuery.getInstance().getFinanceorgIDsByAccountingbookIDs(new String[] {voucher.getPk_accountingbook()});
		String YYZK010 = SysinitAccessor.getInstance().getParaString(orgs[0], "YYZK010");
		if("2".equals(YYZK010)){
			intSortIndex = new int[] {
					VoucherKey.D_EXPLANATION,
					VoucherKey.D_PK_ACCSUBJ,
					VoucherKey.D_PK_CURRTYPE,
					VoucherKey.D_ASSID,
					VoucherKey.D_DIRECTION
			};
			if(tmpdebit != null){
				// 记录原始摘要并且去除空格
				for (DetailVO tmpdetailVO : tmpdebit) {
					String tmpexplanation = tmpdetailVO.getExplanation();
					tmpdetailVO.setExplanationOrigin(tmpdetailVO.getExplanation());
					if(StringUtils.isNotBlank(tmpexplanation)){
						String removeBlankStr = tmpexplanation.replaceAll(" ","");
						tmpdetailVO.setExplanation(removeBlankStr);
					}

				}
			}
		}
		// end edit by aden
		tmpdebit = DetailTool.sumDetails(tmpdebit, intSortIndex);
		// start edit by aden 2023-06-05 14:40:25
		if("2".equals(YYZK010)){
			if(tmpdebit != null){
				// 还原原始摘要
				for (DetailVO sumdetailVO : tmpdebit) {
					sumdetailVO.setExplanation(sumdetailVO.getExplanationOrigin());
				}
			}
		}
		// end edit by aden
		List<DetailVO> vecdetails = new ArrayList<DetailVO>();
		if (nosumdetails.size() > 0) {
			for (DetailVO detail : nosumdetails) {
				vecdetails.add(detail);
			}
		}

		if (tmpdebit != null) {
			for (DetailVO detail : tmpdebit) {
				if (detail.getAssid() != null && detail.getAssid().equals("null")){
					detail.setAssid(null);}
				if (detail.getDebitquantity().doubleValue() != 0 && detail.getDebitamount().doubleValue() != 0) {
					detail.setPrice(detail.getDebitamount().div(detail.getDebitquantity()));
				}
				vecdetails.add(detail);
			}
		}

		List<DetailVO> sortted_detail = new ArrayList<DetailVO>();
		for (int i = 0; i < subjcode_sequence.size(); i++) {
			for (DetailVO detailVO : vecdetails) {
				if (subjcode_sequence.get(i).equals(detailVO.getAccsubjcode())) {
					sortted_detail.add(detailVO);
					if (!detailVO.getLocaldebitamount().equals(new UFDouble(0))
							&& !detailVO.getLocalcreditamount().equals(new UFDouble(0))) {
						DetailVO ec = (DetailVO) detailVO.clone();

						detailVO.setLocalcreditamount(new UFDouble(0));
						detailVO.setCreditamount(new UFDouble(0));
						detailVO.setFraccreditamount(new UFDouble(0));
						detailVO.setCreditquantity(new UFDouble(0));

						ec.setLocaldebitamount(new UFDouble(0));
						ec.setDebitamount(new UFDouble(0));
						ec.setFracdebitamount(new UFDouble(0));
						ec.setDebitquantity(new UFDouble(0));
						sortted_detail.add(ec);
					}
				}
			}
		}

		//ADD BY WW 2024-03-26 按照detailIndex倒序排列一下,实现科目顺序与汇总前保持一致
		VOSortUtils.ascSort(sortted_detail,new String[]{"detailindex"});
		if (sortted_detail.size() > 0) {
			for (int i = 0; i < sortted_detail.size(); i++){
				sortted_detail.get(i).setDetailindex(Integer.valueOf(i + 1));}
			voucher.setDetails(sortted_detail.toArray(new DetailVO[0]));
		}

		VoucherMDVO mdVO = transVoucherVO(voucher);
//		DetailVO[] mdDetails = voucher.getDetails();
//		if (mdDetails.length > 0) {
//			List<VoucherDetailMDVO> detailvos = new ArrayList<VoucherDetailMDVO>();
//			for (DetailVO detail : mdDetails) {
//				VoucherDetailMDVO detailMDVO = new VoucherDetailMDVO(detail);
//				// 辅助核算显示名称
//				AssVO[] ass = detail.getAss();
//				if (ass != null && ass.length > 0) {
//					String showAss = ShowContentCenter.getShowAss(voucher.getPk_accountingbook(), ass);
//					detailMDVO.setAssname(showAss);
//				}
//				detailvos.add(detailMDVO);
//			}
//			mdVO.setDetailMDVOs(detailvos.toArray(new VoucherDetailMDVO[0]));
//		}
		return mdVO;
	}

	/**
	 * 导出XML
	 */
	public void exportXML(String[] pk_vouchers, String filepath, boolean fileground) throws BusinessException {
		// 只支持按选中凭证导出
		if (fileground) {
			VoucherVO[] vouchers = null;
			if (pk_vouchers == null || pk_vouchers.length == 0) {
				throw new GlBusinessException(NCLangRes4VoTransl.getNCLangRes().getStrByID(
						"20021005", "UPP20021005-000488")/*
				 * @res
				 * "没有被选中的凭证！请先选择凭证，然后导出。"
				 */);
			}
			try {
				vouchers = new VoucherBO().queryByPks(pk_vouchers);
			} catch (Exception e) {
				throw new BusinessException(e.getMessage());
			}

			if (vouchers != null && vouchers.length != 0) {
				String pk_accountingbook = vouchers[0].getPk_accountingbook();
				String pk_org = AccountBookUtil.getPk_orgByAccountBookPk(pk_accountingbook);
				String pk_group = InvocationInfoProxy.getInstance().getGroupId();
				IGeneralAccessor accessor = GeneralAccessorFactory.getAccessor(IOrgMetaDataIDConst.ORG);
				IBDData orgVO = accessor.getDocByPk(pk_org);
				IBDData groupVO = accessor.getDocByPk(pk_group);

				Document document = generateDocument();
				Element root = document.createElement("ufinterface");
				root.setAttribute("account", "develop");
				root.setAttribute("billtype", "vouchergl");
				root.setAttribute("businessunitcode", "develop");
				root.setAttribute("filename", null);
				root.setAttribute("groupcode", groupVO == null ? null : groupVO.getCode());
				root.setAttribute("isexchange", null);
				root.setAttribute("orgcode", orgVO == null ? null : orgVO.getCode());
				root.setAttribute("receiver", pk_group);
				root.setAttribute("replace", null);
				root.setAttribute("roottag", null);
				root.setAttribute("sender", "001");

				for (int i = 0; i < vouchers.length; i++) {
					vouchers[i].getDiffanalys();
					org.w3c.dom.Node voucherNode = XML_VoucherTranslator.getVoucherNode(document, vouchers[i]);
					root.appendChild(voucherNode);
				}
				document.appendChild(root);
				StringBuffer fileBuffer = new StringBuffer();
				XML_VoucherTranslator.writeXMLFormatString(fileBuffer, document, -2);
				try {
					XML_VoucherTranslator.saveToFile(filepath, fileBuffer);
				} catch (Exception e) {
					throw new BusinessException(e.getMessage());
				}
			}

		} else {
			if (pk_vouchers == null || pk_vouchers.length == 0) {
				throw new GlBusinessException(NCLangRes4VoTransl.getNCLangRes().getStrByID(
						"20021005", "UPP20021005-000488")/*
				 * @res
				 * "没有被选中的凭证！请先选择凭证，然后导出。"
				 */);
			}
			GLPubProxy.getRemoteVoucherList().outputVoucherByPKs(pk_vouchers);
		}

	}

	private AssVO[] getNewAssVOs(AccAssVO[] accAssVOs, AssVO[] oldAssVOs) {

		if (accAssVOs == null || accAssVOs.length == 0){
			return null;}

		Map<String, AssVO> oldAssMap = new HashMap<String, AssVO>();

		if (oldAssVOs != null) {
			for (AssVO assVo : oldAssVOs) {
				oldAssMap.put(assVo.getPk_Checktype(), assVo);
			}
		}

		List<AssVO> rtList = new ArrayList<AssVO>();
		for (AccAssVO accAssVo : accAssVOs) {
			if (oldAssMap.containsKey(accAssVo.getPk_entity())) {
				rtList.add(oldAssMap.get(accAssVo.getPk_entity()));
			} else {
				AssVO assVo = new AssVO();
				assVo.setPk_Checktype(accAssVo.getPk_entity());
				rtList.add(assVo);
			}
		}

		return rtList.toArray(new AssVO[0]);
	}

	/**
	 * 补充前端需要的信息
	 * @param result
	 * @return
	 * @throws BusinessException
	 */
	private HashMap<String, Object> processResult(HashMap<String, Object> result) throws BusinessException{
		@SuppressWarnings("unchecked")
		Map<String, String> errorInfoMap = (Map<String, String>)result.get("error");
		@SuppressWarnings("unchecked")
		Map<String, String> warnInfoMap = (Map<String, String>)result.get("warn");
		Set<String> voucherPkSet = new HashSet<>();
		if(errorInfoMap != null) {
			voucherPkSet.addAll(errorInfoMap.keySet());
		}
		if(warnInfoMap != null) {
			voucherPkSet.addAll(warnInfoMap.keySet());
		}

		Map<String, Map<String, Map<String, String>>> voucherInfoMap = new HashMap<>();
		if(voucherPkSet.size() > 0) {
			VoucherVO[] vouchers = new VoucherBO().queryByPks(voucherPkSet.toArray(new String[0]), false);
			for(VoucherVO voucherVO : vouchers) {
				Map<String, Map<String, String>> voucherInfo = generateVoucherInfo(voucherVO);
				voucherInfoMap.put(voucherVO.getPk_voucher(), voucherInfo);
			}
		}

		if(errorInfoMap != null) {
			Map<String, Map<String, Map<String, String>>> errorInfoMapNew = new HashMap<>();
			Set<String> pk_vouchers = errorInfoMap.keySet();
			for(String pk_voucher : pk_vouchers) {
				Map<String, Map<String, String>> voucherInfo = voucherInfoMap.get(pk_voucher);
				String errorStr = NCLangRes4VoTransl.getNCLangRes().getStrByID("2002gl55","UPP2002gl55-000412")/*@res "失败"*/;
				voucherInfo.put("result", generateValueObj(errorStr, errorStr));
				voucherInfo.put("reason", generateValueObj(errorInfoMap.get(pk_voucher), errorInfoMap.get(pk_voucher)));
				errorInfoMapNew.put(pk_voucher, voucherInfo);
			}
			result.put("error", errorInfoMapNew);
		}

		if(warnInfoMap != null) {
			Map<String, Map<String, Map<String, String>>> warnInfoMapNew = new HashMap<>();
			Set<String> pk_vouchers = warnInfoMap.keySet();
			for(String pk_voucher : pk_vouchers) {
				Map<String, Map<String, String>> voucherInfo = voucherInfoMap.get(pk_voucher);
				String warnStr = NCLangRes4VoTransl.getNCLangRes().getStrByID("glpub_0","02002003-0034")/* @res "警告" */;
				voucherInfo.put("result", generateValueObj(warnStr, warnStr));
				voucherInfo.put("reason", generateValueObj(warnInfoMap.get(pk_voucher), warnInfoMap.get(pk_voucher)));
				warnInfoMapNew.put(pk_voucher, voucherInfo);
			}
			result.put("warn", warnInfoMapNew);
		}

		return result;
	}

	private Map<String, Map<String, String>> generateVoucherInfo(VoucherVO voucherVO){
		String pk_voucher = voucherVO.getPk_voucher();
		String pk_accountingbook = voucherVO.getPk_accountingbook();
		String prepareddate = voucherVO.getPrepareddate().toStdString();
		String pk_vouchertype = voucherVO.getPk_vouchertype();
		int no = voucherVO.getNo();
		String explanation = voucherVO.getExplanation();

		Map<String, Map<String, String>> result = new HashMap<>();

		String bookName = AccountBookUtil.getAccountingBookNameByPk(pk_accountingbook);
		result.put("pk_accountingbook", generateValueObj(pk_accountingbook, bookName));

		result.put("prepareddate", generateValueObj(prepareddate, prepareddate));

		IBDData voucherTypeBD = GeneralAccessorFactory.getAccessor(IBDMetaDataIDConst.VOUCHERTYPE).getDocByPk(pk_vouchertype);
		result.put("pk_vouchertype", generateValueObj(pk_voucher, voucherTypeBD.getName().toString()));

		result.put("num", generateValueObj(no + "", no + ""));

		result.put("explanation", generateValueObj(explanation, explanation));

		return result;
	}

	private Map<String, String> generateValueObj(String value, String display){
		Map<String, String> valueObj = new HashMap<String, String>();
		valueObj.put("value", value);
		valueObj.put("display", display);
		return valueObj;
	}

	/**
	 * 获取处理结果，有报错直接全部回滚
	 * @param results
	 * @param pk_vouchers
	 * @param result
	 * @param isList
	 * @return
	 * @throws BusinessException
	 */
	private HashMap<String,Object> getResultMap(OperationResultVO[] results,String[] pk_vouchers
			,HashMap<String,Object> result,boolean isList) throws BusinessException{
		HashMap<String,Object> resultMap = new HashMap<String,Object>();
		Map<String,Object> warnMap=new HashMap<String,Object>();
		if (results != null) {
			for (OperationResultVO opresult : results) {
				if (OperationResultVO.ERROR == opresult.m_intSuccess) {
					throw new BusinessException(opresult.m_strDescription);
				}else if(OperationResultVO.WARN == opresult.m_intSuccess) {
					warnMap.put(opresult.m_strPK, opresult.m_strDescription);
				}
			}
		}
		HashMap<String, String> errResult = (HashMap<String, String>)result.get("error");
		VoucherVO[] newVOs = new VoucherBO().queryByPks(pk_vouchers,!isList);//FIXME 查询凭证VO
		if (newVOs != null && newVOs.length > 0) {
			List<VoucherMDVO> vos = new ArrayList<VoucherMDVO>();
			Set<String> systemcodes=new HashSet<String>();
			for (VoucherVO voucherVO : newVOs) {
				systemcodes.add(voucherVO.getPk_system());
			}
			Map<String, String> systemMap = new VoucherWebQryBO().getSystemName(systemcodes.toArray(new String[0]));
			for (VoucherVO voucherVO : newVOs) {
				voucherVO.setSystemname(systemMap.get(voucherVO.getPk_system()));
				vos.add(new VoucherMDVO(voucherVO,!isList));
			}
			if(!isList) {
				Map<String, Object> transVoucher = new VoucherWebQryBO().transVoucher(vos.get(0));
				vos = new ArrayList<VoucherMDVO>();
				vos.add((VoucherMDVO) transVoucher.get("voucher"));
				resultMap.put("paraInfo", transVoucher.get("paraInfo"));//卡片界面放入处理好的paraInfo add by qinhaof
			}
			resultMap.put("success", vos);
		}
		if(warnMap.size()>0) {
			resultMap.put("warn",warnMap);
		}
		if(errResult!=null&&errResult.size()>0){
			resultMap.put("error", errResult);
		}
		return resultMap;
	}

	public void setDefaultValue(VoucherVO voucherVO) throws BusinessException {
		if (StringUtil.isEmptyWithTrim(voucherVO.getPk_accountingbook())) {
			throw new BusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("2002004501", "UPP2002004501-000040")/*
			 * @res "请选择财务核算账簿！"
			 */);
		}

		if (StringUtil.isEmptyWithTrim(voucherVO.getPk_org())) {
			//权限过滤
			BUWithBookRefModel refmodel=new BUWithBookRefModel(voucherVO.getPk_accountingbook());
			List<OrgVO> orgvos = refmodel.getPowerBUOrgs();
			if(orgvos!=null&&orgvos.size()==0){
				AccountingBookVO accBookVO = (AccountingBookVO) new BaseDAO().retrieveByPK(AccountingBookVO.class,
						voucherVO.getPk_accountingbook());
				for (OrgVO orgVO : orgvos) {
					if(orgVO.getPk_org().equals(accBookVO.getPk_relorg())){
						voucherVO.setPk_org(accBookVO.getPk_relorg());
						break;
					}
				}
			}
		}
		if (StringUtil.isEmptyWithTrim(voucherVO.getPk_org_v())&&!StringUtil.isEmptyWithTrim(voucherVO.getPk_org())) {
			HashMap<String, String> vidMap = NCLocator.getInstance().lookup(IBasicOrgUnitPubService_C.class)
					.getNewVIDSByOrgIDSAndDate(new String[] { voucherVO.getPk_org() },voucherVO.getPrepareddate().asEnd());
			if (vidMap.containsKey(voucherVO.getPk_org())) {
				voucherVO.setPk_org_v(vidMap.get(voucherVO.getPk_org()));
			}
		}

		if (StringUtil.isEmptyWithTrim(voucherVO.getPk_group())){
			voucherVO.setPk_group(InvocationInfoProxy.getInstance().getGroupId());}
		if (StringUtil.isEmptyWithTrim(voucherVO.getPk_system())){
			voucherVO.setPk_system(GlNodeConst.NCGL);}
		if (voucherVO.getCreationtime() != null && StringUtil.isEmptyWithTrim(voucherVO.getPk_voucher())){
			voucherVO.setCreationtime(new UFDateTime(InvocationInfoProxy.getInstance().getBizDateTime()));}
		if (voucherVO.getModifyflag() == null) {
			voucherVO.setModifyflag(VoucherModflagTool.getVoucherHeadModFlag(VoucherModflagTool.DEFAULT_CTRL));
		}

		if(StringUtil.isEmptyWithTrim(voucherVO.getYear())||StringUtil.isEmptyWithTrim(voucherVO.getPeriod())){
			AccountCalendar calendar = CalendarUtilGL.getAccountCalendarByAccountBook(voucherVO.getPk_accountingbook());
			calendar.setDate(voucherVO.getPrepareddate());
			voucherVO.setYear(calendar.getYearVO().getPeriodyear());
			voucherVO.setPeriod(calendar.getMonthVO().getAccperiodmth());
		}else if(!StringUtil.isEmptyWithTrim(voucherVO.getPeriod())&&voucherVO.getPeriod().length()>3){
			String[] yearmth=voucherVO.getPeriod().split("-");
			if(yearmth.length>1){
				voucherVO.setPeriod(yearmth[1]);
			}else{
				AccountCalendar calendar = CalendarUtilGL.getAccountCalendarByAccountBook(voucherVO.getPk_accountingbook());
				calendar.setDate(voucherVO.getPrepareddate());
				voucherVO.setYear(calendar.getYearVO().getPeriodyear());
				voucherVO.setPeriod(calendar.getMonthVO().getAccperiodmth());
			}
		}

		if(StringUtil.isEmptyWithTrim(voucherVO.getM_adjustperiod())){
			voucherVO.setM_adjustperiod(voucherVO.getPeriod());
		}else if(voucherVO.getM_adjustperiod().length()>3){
			String[] yearmth=voucherVO.getM_adjustperiod().split("-");
			if(yearmth.length>1){
				voucherVO.setM_adjustperiod(yearmth[1]);
			}
		}
		if (StringUtil.isEmptyWithTrim(voucherVO.getPk_prepared())||!StringUtil.isEmptyWithTrim(voucherVO.getPk_voucher())){
			//modify by qinhaof 签字补录凭证信息也走此逻辑，这里处理为签字补录信息不更新制单人
			//modify by zhaoshya OpenAPI修改凭证也走到这，制单人不能使用环境变量的
			if(InvocationInfoProxy.getInstance().getProperty("appcode")!=null
					&&!GlNodeConst.GLNODE_VOUCHERSIGN.equals(InvocationInfoProxy.getInstance().getProperty("appcode"))) {
				voucherVO.setPk_prepared(InvocationInfoProxy.getInstance().getUserId());
			}
		}
		if (StringUtil.isEmptyWithTrim(voucherVO.getCreator())){
			voucherVO.setCreator(voucherVO.getPk_prepared());}
		if (voucherVO.getDiscardflag() == null){
			voucherVO.setDiscardflag(UFBoolean.FALSE);}
		if (voucherVO.getDetailmodflag() == null){
			voucherVO.setDetailmodflag(UFBoolean.TRUE);}

		Object[] details = voucherVO.getDetail().toArray();
		if (details != null) {
			Set<String> unitvSet = new HashSet<String>();
			Set<String> unitSet = new HashSet<String>();

			Set<String> profitset=new HashSet<String>();

			//暂存凭证的detailindex从1开始，解决凭证导出时第一条分录为空的问题
			int detailindex = 1;
			for (Object detail : details) {
				DetailVO detailVO=(DetailVO) detail;
				detailVO.setDetailindex(detailindex++);
				detailVO.setPk_org(voucherVO.getPk_org());
				detailVO.setPk_org_v(voucherVO.getPk_org_v());
				if (!StringUtil.isEmptyWithTrim(detailVO.getPk_unit_v())&&StringUtil.isEmptyWithTrim(detailVO.getPk_unit())) {
					unitvSet.add(detailVO.getPk_unit_v());
				}else if(StringUtil.isEmptyWithTrim(detailVO.getPk_unit_v())&&!StringUtil.isEmptyWithTrim(detailVO.getPk_unit())){
					unitSet.add(detailVO.getPk_unit());
				}else if(StringUtil.isEmptyWithTrim(detailVO.getPk_unit_v())&&StringUtil.isEmptyWithTrim(detailVO.getPk_unit())){
					detailVO.setPk_unit(voucherVO.getPk_org());
					detailVO.setPk_unit_v(voucherVO.getPk_org_v());
				}

				if(!StringUtils.isEmpty(detailVO.getPk_liabilitycenter())&&StringUtils.isEmpty(detailVO.getPk_liabilitycenter_v())) {
					profitset.add(detailVO.getPk_liabilitycenter());
				}

				detailVO.setPrepareddate(voucherVO.getPrepareddate());
				if(StringUtil.isEmptyWithTrim(detailVO.getVerifydate()))
				{
					detailVO.setVerifydate(voucherVO.getPrepareddate().toString());
				}
			}

			HashMap<String, String> orgMap=null;
			if (unitvSet.size() > 0) {
				orgMap = NCLocator.getInstance().lookup(IBasicOrgUnitPubService_C.class)
						.getOrgIDSByVIDS(unitvSet.toArray(new String[0]));

			}
			HashMap<String, String> vidMap=null;
			if (unitSet.size() > 0) {
				vidMap = NCLocator.getInstance().lookup(IBasicOrgUnitPubService_C.class)
						.getNewVIDSByOrgIDSAndDate(unitSet.toArray(new String[0]), voucherVO.getPrepareddate().asEnd());
			}

			if(orgMap!=null||vidMap!=null){
				if(orgMap==null){
					orgMap=new HashMap<String,String>();}
				if(vidMap==null){
					vidMap=new HashMap<String,String>();}
				for (Object detail : details) {
					DetailVO detailVO=(DetailVO) detail;
					if (!StringUtil.isEmptyWithTrim(detailVO.getPk_unit_v())&&StringUtil.isEmptyWithTrim(detailVO.getPk_unit())) {
						detailVO.setPk_unit(orgMap.get(detailVO.getPk_unit_v()));
					}else if (StringUtil.isEmptyWithTrim(detailVO.getPk_unit_v())&&!StringUtil.isEmptyWithTrim(detailVO.getPk_unit())) {
						detailVO.setPk_unit_v(vidMap.get(detailVO.getPk_unit()));
					}
				}
			}

			boolean isliabilitystart = GLParaAccessor.isLbtCenterStart(voucherVO.getPk_accountingbook()).booleanValue();
			if(isliabilitystart&&profitset.size()>0) {
				//只有利润中心没有利润中心版本，补充利润中心版本
				Map<String, ProfitcenterVersionVO> versionMap=NCLocator.getInstance().lookup(IProfitCenterPubService.class)
						.queryVersion(profitset.toArray(new String[0]), voucherVO.getPrepareddate());
				if(versionMap!=null&&versionMap.size()>0) {
					for (Object detail : details) {
						DetailVO detailVO=(DetailVO) detail;
						if(!StringUtils.isEmpty(detailVO.getPk_liabilitycenter())&&StringUtils.isEmpty(detailVO.getPk_liabilitycenter_v())) {
							ProfitcenterVersionVO profitvo = versionMap.get(detailVO.getPk_liabilitycenter());
							if(profitvo!=null) {
								detailVO.setPk_liabilitycenter_v(profitvo.getPk_vid());
							}
						}
					}
				}

			}
		}
	}

	private Map<String, Object> getResultMap(OperationResultVO[] results,VoucherVO vo) throws BusinessException {
		Map<String, Object> map = new HashMap<String, Object>();
		if (results != null && results.length > 0) {
			vo = (VoucherVO) results[0].m_userIdentical;
			if(vo.isHasRefVerify()){
				try {
					VoucherVO newVoucher = NCLocator.getInstance().lookup(IVoucher.class).queryByPk(vo.getPk_voucher());
					vo = (VoucherVO)newVoucher.clone();
				} catch (BusinessException e) {
					throw new GlBusinessException(e.getMessage());
				}
			}

			//查询是否已经协同
			reconcileCheck(vo);

			StringBuffer waringMessage=new StringBuffer();
			StringBuffer errorMessage=new StringBuffer();
			for (OperationResultVO result : results) {
				if (OperationResultVO.ERROR == result.m_intSuccess) {
					errorMessage.append(result.m_strDescription+"\n");
				} else {

					if (OperationResultVO.WARN == result.m_intSuccess) {
						waringMessage.append(result.m_strDescription+"\n");
					}
				}
			}
			if(errorMessage.length()>0){
				throw new BusinessException(errorMessage.toString());}
			//辅助核算档案多版本
			GLAssDocVersionUtil.adjustAssDocVName(vo.getDetails(), VoucherKey.D_ASS, VoucherKey.V_PREPAREDDATE, null);
			VoucherMDVO mdVO = transVoucherVO(vo);
			VoucherDetailMDVO[] details=mdVO.getDetailMDVOs();
			boolean isShowSum=false;
			if(details!=null){
				for(VoucherDetailMDVO detail:details){
					if(detail.getIsShowNum().booleanValue()||
							!UFDouble.ZERO_DBL.equals(detail.getDebitquantity())||
							!UFDouble.ZERO_DBL.equals(detail.getCreditquantity())){
						//录入了金额的也要显示
						isShowSum=true;
						break;
					}
				}
			}
			map.put("success", mdVO);
			map.put("isShowNum", isShowSum);
			if(waringMessage.length()>0){
				map.put("warn",waringMessage.toString());}
		}
		return map;
	}

	private void reconcileCheck(VoucherVO vo) throws BusinessException {
		String[] recdetailpks = null;
		HashMap detailpkhashmap = new HashMap();
		try {
			recdetailpks = new ReconcileoccursubDMO().findMatchedSelfDetail(new String[] { vo.getPk_voucher() });
		} catch (Exception e) {
			Logger.error(e.getMessage(), e);
		}
		if (recdetailpks != null && recdetailpks.length > 0) {
			for (int i = 0; i < recdetailpks.length; i++) {
				detailpkhashmap.put(recdetailpks[i], recdetailpks[i]);
			}
			try {
				Vector<DetailVO> details = vo.getDetail();
				if (details != null && details.size() > 0) {
					for (DetailVO detail : details) {
						if (detailpkhashmap.get(detail.getPk_detail()) != null) {
							detail.setIsmatched(UFBoolean.TRUE);
						}
					}
				}
			} catch (Exception e) {
				throw new BusinessException(e.getMessage());
			}
		}
	}

	private VoucherMDVO transVoucherVO(VoucherVO voucher) throws BusinessException {
		VoucherMDVO mdVO = new VoucherMDVO(voucher,true);

		Map<String, String> systemMap = new VoucherWebQryBO().getSystemName(new String[]{voucher.getPk_system()});
		voucher.setSystemname(systemMap.get(voucher.getPk_system()));
		VoucherDetailMDVO[] mdetails=new VoucherWebQryBO().catSubjName(mdVO.getDetailMDVOs());
//		if (mdetails!=null&&mdetails.length > 0) {
//			List<String> accasoas = new ArrayList<String>();
//			for (VoucherDetailMDVO detail : mdetails) {
//				accasoas.add(detail.getPk_accasoa());
//			}
//			AccountVO[] accounts = AccountUtilGL.queryByPks(accasoas.toArray(new String[0]), voucher
//					.getPrepareddate().toStdString());
//			Map<String,AccountVO> accMap=new HashMap<String,AccountVO>();
//			Set<String> numAccasoa=new HashSet<String>();
//			for (AccountVO accountVO : accounts) {
//				if(accountVO!=null&&!StringUtil.isEmptyWithTrim(accountVO.getUnit())){
//					numAccasoa.add(accountVO.getPk_accasoa());
//				}
//				accMap.put(accountVO.getPk_accasoa(), accountVO);
//
//			}
//			Integer langIndex = MultiLangContext.getInstance().getCurrentLangSeq();
//			for (VoucherDetailMDVO detailMDVO : mdetails) {
//				AccountVO account = accMap.get(detailMDVO.getPk_accasoa());
//				if(account!=null){
//					detailMDVO.setAccsubjname(account.getDispname());
//					if(langIndex==2){
//						detailMDVO.setAccsubjname(account.getDispname2());
//					}else if(langIndex==3){
//						detailMDVO.setAccsubjname(account.getDispname3());
//					}else if(langIndex==4){
//						detailMDVO.setAccsubjname(account.getDispname4());
//					}else if(langIndex==5){
//						detailMDVO.setAccsubjname(account.getDispname5());
//					}else if(langIndex==6){
//						detailMDVO.setAccsubjname(account.getDispname6());
//					}
//					detailMDVO.setAccsubjcode(account.getCode());
//					detailMDVO.setAccsubjcashtype(account.getCashtype().toString());
//					detailMDVO.setAccsubjaccproperty(account.getAccproperty()==null?"0":account.getAccproperty().toString());
//					detailMDVO.setAccsubjparallel(account.getParallelaccounts()==null?"N":(account.getParallelaccounts().booleanValue()?"Y":"N"));
//					detailMDVO.setAccsubjnparallel(account.getNparallelaccounts()==null?"N":(account.getNparallelaccounts().booleanValue()?"Y":"N"));
//					detailMDVO.setSettle(true);
//					detailMDVO.setVerify(true);
//					if(numAccasoa.contains(detailMDVO.getPk_accasoa())||
//							!UFDouble.ZERO_DBL.equals(detailMDVO.getDebitquantity())||
//							!UFDouble.ZERO_DBL.equals(detailMDVO.getCreditquantity())) {
//						detailMDVO.setIsShowNum(UFBoolean.TRUE);
//					}
//					detailMDVO.setPk_measdoc(account.getUnit());
//				}
//			}
		mdVO.setDetailMDVOs(mdetails);
//		}
		return mdVO;
	}

	/**
	 * 根据分录上的原币和制单日期，重新取汇率及计算本币
	 * @deprecated 统一使用 nc.gl.utils.rate.VoucherAmountConvertor since 2111
	 * @param tmp_voucher
	 * @param detailTemp
	 * @throws BusinessException
	 */
	@Deprecated
	public static void resetRateAndLocAmout(VoucherVO tmp_voucher, DetailVO detailTemp) throws BusinessException{
		String pk_locCurrtype=Currency.getLocalCurrPK(tmp_voucher.getPk_accountingbook());
		//判断币种
		if(org.apache.commons.lang3.StringUtils.isEmpty(detailTemp.getPk_currtype())) {
			throw new BusinessException("复制的凭证分录币种不能为空");
		}
		//账簿本币汇率
		UFDouble rate2 =
				Currency.getRate(tmp_voucher.getPk_accountingbook(), detailTemp.getPk_currtype(),
						pk_locCurrtype, UFDateTools.convertToUFDate(tmp_voucher.getPrepareddate().toLocalString()));
		UFDouble rate3 = UFDouble.ZERO_DBL;//集团本币汇率
		UFDouble rate4 = UFDouble.ZERO_DBL;//全局本币汇率
		String pk_currtype = detailTemp.getPk_currtype(); //分录币种主键
		String date = tmp_voucher.getPrepareddate().toStdString(); //制单日期
		String pk_accountingbook = tmp_voucher.getPk_accountingbook(); //核算账簿主键
		try {
			//账簿本币汇率模式
			CurrinfoVO currinfo = Currency.getCurrRateInfo(pk_accountingbook, pk_currtype, pk_locCurrtype);
			if(currinfo!=null){
				//rate2 = rate2;
				//汇率计算模式，默认是乘
				boolean localCurrConvmode = currinfo.getConvmode().intValue()==ICurrinfoConst.CONVMODE_MULT;
//        		Integer locCurrDigit = Currency.getCurrDigit(pk_locCurrtype); //账簿本币币种精度

				int[] digitAndRoundtype = nc.itf.fi.pub.Currency.getCurrDigitAndRoundtype(pk_locCurrtype);
				//TODO 后续可以考虑将金额换算逻辑抽取出来，这里重复代码太多了 qinhaof
				if(localCurrConvmode){
					detailTemp.setLocaldebitamount(detailTemp.getDebitamount().multiply(rate2));
					detailTemp.setLocalcreditamount(detailTemp.getCreditamount().multiply(rate2));
				}else{
					if(!UFDouble.ZERO_DBL.equals(rate2)) {
						detailTemp.setLocaldebitamount(detailTemp.getDebitamount().div(rate2));
						detailTemp.setLocalcreditamount(detailTemp.getCreditamount().div(rate2));
					}else {
						detailTemp.setLocaldebitamount(UFDouble.ZERO_DBL);
						detailTemp.setLocalcreditamount(UFDouble.ZERO_DBL);
					}
				}
				detailTemp.setExcrate2(rate2);
			}
			//启用了集团本币，集团本币可以基于原币计算，也可以基于本级计算
			if (Currency.isStartGroupCurr(InvocationInfoProxy.getInstance().getGroupId())) {
				String pk_groupCurrtype = Currency.getGroupCurrpk(InvocationInfoProxy.getInstance().getGroupId());//集团本币主键
				CurrinfoVO groupCurrInfo = null;
//        		Integer groupCurrDigit = Currency.getCurrDigit(pk_groupCurrtype); //集团本币币种精度

				int[] digitAndRoundtype = nc.itf.fi.pub.Currency.getCurrDigitAndRoundtype(pk_groupCurrtype);

				//基于原币
				if(Currency.isGroupRawConvertModel(InvocationInfoProxy.getInstance().getGroupId())){
					rate3 = Currency.getRateByOrg(InvocationInfoProxy.getInstance().getGroupId(),pk_accountingbook,pk_currtype , new UFDate(date));
					groupCurrInfo = Currency.getCurrRateInfoByOrg(InvocationInfoProxy.getInstance().getGroupId(), pk_currtype, pk_groupCurrtype);
				}else{//基于账簿本币
					rate3 = Currency.getRateByOrg(InvocationInfoProxy.getInstance().getGroupId(),pk_accountingbook,pk_currtype , new UFDate(date));
					groupCurrInfo = Currency.getCurrRateInfoByOrg(InvocationInfoProxy.getInstance().getGroupId(), pk_locCurrtype, pk_groupCurrtype);
				}
				boolean groupCurrConvmode = groupCurrInfo == null || groupCurrInfo.getConvmode().intValue() == ICurrinfoConst.CONVMODE_MULT;
				if(groupCurrConvmode){
					detailTemp.setGroupdebitamount(detailTemp.getDebitamount().multiply(rate3));
					detailTemp.setGroupcreditamount(detailTemp.getCreditamount().multiply(rate3));
				}else{
					if(!UFDouble.ZERO_DBL.equals(rate3)) {
						detailTemp.setGroupdebitamount(detailTemp.getDebitamount().div(rate3));
						detailTemp.setGroupcreditamount(detailTemp.getCreditamount().div(rate3));
					}else {
						detailTemp.setGroupdebitamount(UFDouble.ZERO_DBL);
						detailTemp.setGroupcreditamount(UFDouble.ZERO_DBL);
					}
				}
				detailTemp.setExcrate3(rate3);
			}
			//启用了全局本币，全局本币可以基于原币计算，也可以基于本级计算
			if (Currency.isStartGlobalCurr()) {
				String pk_globalCurrtype = Currency.getGlobalCurrPk(null);
				CurrinfoVO globalCurrInfo = null;
//        		Integer globalCurrDigit = Currency.getCurrDigit(pk_globalCurrtype);

				int[] digitAndRoundtype = nc.itf.fi.pub.Currency.getCurrDigitAndRoundtype(pk_globalCurrtype);

				//基于原币
				if(Currency.isGlobalRawConvertModel(IOrgConst.GLOBEORG)){
					rate4 = Currency.getRateByOrg(IOrgConst.GLOBEORG,pk_accountingbook,pk_currtype , new UFDate(date));
					globalCurrInfo = Currency.getCurrRateInfoByOrg(IOrgConst.GLOBEORG, pk_currtype, pk_globalCurrtype);

				}else{//基于账簿本币
					rate4 = Currency.getRateByOrg(IOrgConst.GLOBEORG,pk_accountingbook,pk_currtype , new UFDate(date));
					globalCurrInfo = Currency.getCurrRateInfoByOrg(IOrgConst.GLOBEORG, pk_locCurrtype, pk_globalCurrtype);
				}
				boolean globalCurrConvmode = globalCurrInfo == null || globalCurrInfo.getConvmode().intValue() == ICurrinfoConst.CONVMODE_MULT;
				if(globalCurrConvmode){
					detailTemp.setGlobaldebitamount(detailTemp.getDebitamount().multiply(rate4));
					detailTemp.setGlobalcreditamount(detailTemp.getCreditamount().multiply(rate4));
				}else{
					if(!UFDouble.ZERO_DBL.equals(rate4)) {
						detailTemp.setGlobaldebitamount(detailTemp.getDebitamount().div(rate4));
						detailTemp.setGlobalcreditamount(detailTemp.getCreditamount().div(rate4));
					}else {
						detailTemp.setGlobaldebitamount(UFDouble.ZERO_DBL);
						detailTemp.setGlobalcreditamount(UFDouble.ZERO_DBL);
					}
				}
				detailTemp.setExcrate4(rate4);
			}
		} catch (BusinessException e1) {
			Logger.error(e1.getMessage() ,e1);
		}
	}

	/**
	 * 重置assid，尽可能减小清理辅助核算功能带来的对凭证录入的影响
	 * @param voucherVO
	 */
	private void resetVoucherAssid(VoucherVO voucherVO) throws BusinessException {
		String pk_group = InvocationInfoProxy.getInstance().getGroupId();
		IFreevaluePub service = NCLocator.getInstance().lookup(IFreevaluePub.class);
		Vector<DetailVO> details = voucherVO.getDetail();
		if(details != null && details.size() > 0) {
			for(DetailVO detail : details) {
				AssVO[] assVOs = detail.getAss();
				if(assVOs != null && assVOs.length > 0) {
					String assid = service.getAssID(assVOs, true, pk_group, Module.GL);
					detail.setAssid(assid);
				}
			}
		}
	}

	public Map<String, Object> saveVoucherIsCheck(VoucherVO voucherVO, boolean isAdd, UFDate busidate,boolean isCheck)
			throws BusinessException {
		if (voucherVO == null){
			return null;}
		resetVoucherAssid(voucherVO);
		if(StringUtils.isEmpty(voucherVO.getPk_voucher())) {
			voucherVO.setPk_prepared(InvocationInfoProxy.getInstance().getUserId());
		}
		new VoucherSaveValidate().validate(voucherVO);
		setDefaultValue(voucherVO);

		// 暂存凭证保存时，自动保存为正常凭证
		voucherVO.setTempsaveflag(UFBoolean.FALSE);
		Set<String> accasoas=new HashSet<String>();
		Object[] details = voucherVO.getDetail().toArray();
		for (Object detailvo : details) {
			DetailVO detail=(DetailVO) detailvo;
			detail.setTempsaveflag(UFBoolean.FALSE);
			accasoas.add(detail.getPk_accasoa());
		}

		OperationResultVO[] results = NCLocator.getInstance().lookup(IVoucher.class).save(voucherVO, isCheck? Boolean.TRUE:Boolean.FALSE);
		Map<String, Object> voucherMap = getResultMap(results,voucherVO);

		Map<String, Object> map = new HashMap<String, Object>();
		// 附属信息
		Map<String, Object> paraInfo = new AccountingbookQryBO().queryBookCombineInfo(voucherVO.getPk_accountingbook(),
				voucherVO.getPrepareddate().toStdString(),true);
		if (isAdd) {
			// 新增保存返回下一张凭证号
			Map<String, Integer> voucherNo = new VoucherWebQryBO().getVoucherNo(voucherVO.getPk_accountingbook(),
					busidate, voucherVO.getPk_vouchertype());
			paraInfo.put("next", voucherNo);
		}

		paraInfo.put("isShowNum",voucherMap.get("isShowNum"));

		if(voucherMap.get("success")!=null&&(boolean)paraInfo.get("isVerify")){
			//需要即时核销，寻找第一个核销科目行号
			VoucherMDVO mdvo=(VoucherMDVO) voucherMap.get("success");
			String pk_glorgbook = mdvo.getPk_accountingbook();
			String prepareddate = mdvo.getPrepareddate().toString();
			String[] startAccountPks = GLPubProxy.getRemoteVerifyobj().getAllPk_accasoaOfVerifyObj(new String[] {pk_glorgbook},prepareddate);
			if (startAccountPks!= null && startAccountPks.length > 0){
				paraInfo.put("verifyIndex", getVerifyDetailVO(mdvo,startAccountPks));
			}

		}
		map.put("voucher", voucherMap);
		map.put("paraInfo", paraInfo);

		return map;
	}
	private Document generateDocument() throws BusinessException {
		try {
			Document document  = DocumentBuilderFactory.newDefaultInstance().newDocumentBuilder().newDocument();
			return document;
		} catch (ParserConfigurationException e) {
			throw new BusinessException("????Document???", e);
		}
	}
}
